﻿#include "text.h"

/*
 * 这是一个Text中极为重要的函数,接收实际的数据长度以及数据类型信息
 * 将前MessageText的前2/3/4位字节数组拼接出来
 * formate:数据的类型枚举,需要利用前6个bit
 * formateLength:数据的字节大小,等价于sizeof(data)
 * dataLength:数据的数量,而非字节长度
 */
QByteArray GetHeader(SecsEnum::Formate formate,
                     SecsEnum::FormateLength formateLength,
                     int datalength)
{
    int FormateByte = 1;

    if(datalength * formateLength > 0xff)
    {
        FormateByte = 2;
    }

    if(datalength * formateLength > 0xffff)
    {
        FormateByte = 3;
    };

    QByteArray array;

    array.append(formate | FormateByte);

    array.append((static_cast<char>((datalength * formateLength) & 0xFF)));

    if(datalength * formateLength > 0xff)
    {
        array.append((static_cast<char>(((datalength * formateLength) >> 8) & 0xFF)));
    }

    if(datalength * formateLength > 0xffff)
    {
        array.append((static_cast<char>(((datalength * formateLength) >> 16) & 0xFF)));
    }

    return array;
}


struct TextASCIIPrivate
{
    TextASCII* _this;
    TextASCIIPrivate(TextASCII* p);
    QString value;
};

TextASCIIPrivate::TextASCIIPrivate(TextASCII *p)
{
    _this = p;
}

TextASCII::TextASCII()
{
    d = std::make_shared<TextASCIIPrivate>(this);
}

TextASCII::TextASCII(QString value)
{
    d = std::make_shared<TextASCIIPrivate>(this);
    d->value = value;
}

int TextASCII::getLength()
{
    return d->value.size() * SecsEnum::C_LENGTH;
}

QByteArray TextASCII::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::ASCII,
                           SecsEnum::C_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::QStringToByteArray(d->value));
    return array;
}

QString TextASCII::getString(int level)
{
    QString indent(level * 4, ' ');

    if (getLength() == 0)
    {
        return indent + "<ASCII value="">";
    }

    else
    {
        return indent + QString("<ASCII value=").append(d->value).append(">");
    }
}


struct TextBinaryPrivate
{
    TextBinary* _this;
    TextBinaryPrivate(TextBinary* p);
    std::vector<char> value;
};


TextBinaryPrivate::TextBinaryPrivate(TextBinary *p)
{
    _this = p;
}

TextBinary::TextBinary(std::vector<char> value)
{
    d = std::make_shared<TextBinaryPrivate>(this);
    d->value = value;
}

int TextBinary::getLength()
{
    return d->value.size() * SecsEnum::C_LENGTH;
}

QByteArray TextBinary::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::BINARY,
                           SecsEnum::C_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::CharListToByteArray(d->value));
    return array;
}

QString TextBinary::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<Binary length=%1 ").arg(d->value.size());

    str.append("element={");
    for(char element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");

    return indent + str;
}


struct TextBooleanPrivate
{
    TextBoolean* _this;
    TextBooleanPrivate(TextBoolean* p);
    bool value;
};

TextBooleanPrivate::TextBooleanPrivate(TextBoolean *p)
{
    _this = p;
}

TextBoolean::TextBoolean()
{
    d = std::make_shared<TextBooleanPrivate>(this);
}

TextBoolean::TextBoolean(bool value)
{
    d = std::make_shared<TextBooleanPrivate>(this);
    d->value = value;
}

int TextBoolean::getLength()
{
    return 1;
}

QByteArray TextBoolean::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::BOOLEAN,
                           SecsEnum::C_LENGTH,
                           1));
    array.append(ConversionUtil::BoolToByteArray(d->value));
    return array;
}

QString TextBoolean::getString(int level)
{
    QString indent(level * 4, ' ');

    return indent + (d->value ? "<Boolean value=True>" : "<Boolean value=False>");
}


struct TextF4Private
{
    TextF4* _this;
    TextF4Private(TextF4* p);
    std::vector<float> value;
};


TextF4Private::TextF4Private(TextF4 *p)
{
    _this = p;
}

TextF4::TextF4()
{
    d = std::make_shared<TextF4Private>(this);
}

TextF4::TextF4(std::vector<float> value)
{
    d = std::make_shared<TextF4Private>(this);
    d->value = value;
}

int TextF4::getLength()
{
    return d->value.size() * SecsEnum::F4_LENGTH;
}

QByteArray TextF4::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::F4,
                           SecsEnum::F4_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::F4ListToByteArray(d->value));
    return array;
}

QString TextF4::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<F4 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(float element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextF8Private
{
    TextF8* _this;
    TextF8Private(TextF8* p);
    std::vector<double> value;
};

TextF8Private::TextF8Private(TextF8 *p)
{
    _this = p;
}

TextF8::TextF8()
{
    d = std::make_shared<TextF8Private>(this);
}

TextF8::TextF8(std::vector<double> value)
{
    d = std::make_shared<TextF8Private>(this);
    d->value = value;
}

int TextF8::getLength()
{
    return d->value.size() * SecsEnum::F8_LENGTH;
}

QByteArray TextF8::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::F8,
                           SecsEnum::F8_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::F8ListToByteArray(d->value));
    return array;
}

QString TextF8::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<F8 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(float element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}

struct TextI1Private
{
    TextI1* _this;
    TextI1Private(TextI1* p);
    std::vector<qint8> value;
};

TextI1Private::TextI1Private(TextI1 *p)
{
    _this = p;
}

TextI1::TextI1()
{
    d = std::make_shared<TextI1Private>(this);
}

TextI1::TextI1(std::vector<qint8> value)
{
    d = std::make_shared<TextI1Private>(this);
    d->value = value;
}

int TextI1::getLength()
{
    return d->value.size() * SecsEnum::I1_LENGTH;
}

QByteArray TextI1::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::I1,
                           SecsEnum::I1_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::I1ListToByteArray(d->value));
    return array;
}

QString TextI1::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<I1 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(qint8 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextI2Private
{
    TextI2* _this;
    TextI2Private(TextI2* p);
    std::vector<qint16> value;
};

TextI2Private::TextI2Private(TextI2 *p)
{
    _this = p;
}

TextI2::TextI2()
{
    d = std::make_shared<TextI2Private>(this);
}

TextI2::TextI2(std::vector<qint16> value)
{
    d = std::make_shared<TextI2Private>(this);
    d->value = value;
}

int TextI2::getLength()
{
    return d->value.size() * SecsEnum::I2_LENGTH;
}

QByteArray TextI2::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::I2,
                           SecsEnum::I2_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::I2ListToByteArray(d->value));
    return array;
}

QString TextI2::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<I2 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(qint16 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextI4Private
{
    TextI4* _this;
    TextI4Private(TextI4* p);
    std::vector<qint32> value;
};

TextI4Private::TextI4Private(TextI4 *p)
{
    _this = p;
}

TextI4::TextI4()
{
    d = std::make_shared<TextI4Private>(this);
}

TextI4::TextI4(std::vector<qint32> value)
{
    d = std::make_shared<TextI4Private>(this);
    d->value = value;
}

int TextI4::getLength()
{
    return d->value.size() * SecsEnum::I4_LENGTH;
}

QByteArray TextI4::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::I4,
                           SecsEnum::I4_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::I4ListToByteArray(d->value));
    return array;
}

QString TextI4::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<I4 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(qint32 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextI8Private
{
    TextI8* _this;
    TextI8Private(TextI8* p);
    std::vector<qint64> value;
};

TextI8Private::TextI8Private(TextI8 *p)
{
    _this = p;
}

TextI8::TextI8()
{
    d = std::make_shared<TextI8Private>(this);
}

TextI8::TextI8(std::vector<qint64> value)
{
    d = std::make_shared<TextI8Private>(this);
    d->value = value;
}

int TextI8::getLength()
{
    return d->value.size() * SecsEnum::I8_LENGTH;
}

QByteArray TextI8::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::I8,
                           SecsEnum::I8_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::I8ListToByteArray(d->value));
    return array;
}

QString TextI8::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<I8 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(qint64 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextU1Private
{
    TextU1* _this;
    TextU1Private(TextU1* p);
    std::vector<quint8> value;
};

TextU1Private::TextU1Private(TextU1 *p)
{
    _this = p;
}

TextU1::TextU1()
{
    d = std::make_shared<TextU1Private>(this);
}

TextU1::TextU1(std::vector<quint8> value)
{
    d = std::make_shared<TextU1Private>(this);
    d->value = value;
}

int TextU1::getLength()
{
    return d->value.size() * SecsEnum::U1_LENGTH;
}

QByteArray TextU1::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::U1,
                           SecsEnum::U1_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::U1ListToByteArray(d->value));
    return array;
}

QString TextU1::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<U1 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(quint8 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextU2Private
{
    TextU2* _this;
    TextU2Private(TextU2* p);
    std::vector<quint16> value;
};

TextU2Private::TextU2Private(TextU2 *p)
{
    _this = p;
}

TextU2::TextU2()
{
    d = std::make_shared<TextU2Private>(this);
}

TextU2::TextU2(std::vector<quint16> value)
{
    d = std::make_shared<TextU2Private>(this);
    d->value = value;
}

int TextU2::getLength()
{
    return d->value.size() * SecsEnum::U2_LENGTH;
}

QByteArray TextU2::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::U2,
                           SecsEnum::U2_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::U2ListToByteArray(d->value));
    return array;
}

QString TextU2::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<U2 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(quint16 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextU4Private
{
    TextU4* _this;
    TextU4Private(TextU4* p);
    std::vector<quint32> value;
};

TextU4Private::TextU4Private(TextU4 *p)
{
    _this = p;
}

TextU4::TextU4()
{
    d = std::make_shared<TextU4Private>(this);
}

TextU4::TextU4(std::vector<quint32> value)
{
    d = std::make_shared<TextU4Private>(this);
    d->value = value;
}

int TextU4::getLength()
{
    return d->value.size() * SecsEnum::U4_LENGTH;
}

QByteArray TextU4::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::U4,
                           SecsEnum::U4_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::U4ListToByteArray(d->value));
    return array;
}

QString TextU4::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<U4 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(quint32 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}


struct TextU8Private
{
    TextU8* _this;
    TextU8Private(TextU8* p);
    std::vector<quint64> value;
};

TextU8Private::TextU8Private(TextU8 *p)
{
    _this = p;
}

TextU8::TextU8()
{
    d = std::make_shared<TextU8Private>(this);
}

TextU8::TextU8(std::vector<quint64> value)
{
    d = std::make_shared<TextU8Private>(this);
    d->value = value;
}

int TextU8::getLength()
{
    return d->value.size() * SecsEnum::U8_LENGTH;
}

QByteArray TextU8::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::U8,
                           SecsEnum::U8_LENGTH,
                           d->value.size()));
    array.append(ConversionUtil::U8ListToByteArray(d->value));
    return array;
}

QString TextU8::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = QString("<U8 length=%1 ").arg(d->value.size());

    str.append("element={");
    for(quint32 element : d->value)
    {
        str.append("    ");
        str.append(QString::number(element));
    }
    str.append("}");

    str.append(">");
    return indent + str;
}

struct TextListPrivate
{
    TextList* _this;
    TextListPrivate(TextList* p);
    std::vector<Text*> value;
};


TextListPrivate::TextListPrivate(TextList *p)
{
    _this = p;
}

TextList::TextList()
{
    d = std::make_shared<TextListPrivate>(this);
}

TextList::TextList(std::vector<Text *> value)
{
    d = std::make_shared<TextListPrivate>(this);
    d->value = value;
}

int TextList::getLength()
{
    return d->value.size();
}

QByteArray TextList::getByteArray()
{
    QByteArray array;
    array.append(GetHeader(SecsEnum::LIST,
                           SecsEnum::C_LENGTH,
                           d->value.size()));

    for(Text* element : d->value)
    {
        array.append(element->getByteArray());
    }

    return array;
}

QString TextList::getString(int level)
{
    QString indent(level * 4, ' ');

    QString str = indent + QString("<L length=%1 ").arg(getLength());

    for(Text* element : d->value)
    {
        str.append("\n");
        str.append(element->getString(level + 1));
    }

    str.append("\n");
    str.append(indent);
    str.append(">");
    return str;
}

Text *TextList::getItem(int index)
{
    return d->value.at(index);
}

void TextList::addItem(Text *item)
{
    d->value.push_back(item);
}
